home *** CD-ROM | disk | FTP | other *** search
- /* Peek into a user's actions on the bbs.
- * This allows you to follow all stuff, and also
- * send messages and initiate chats...
- * (C) 1994, Johan. K. Reinalda, WG7J
- */
- #include "global.h"
- #ifdef LOOKSESSION
- #include "ctype.h"
- #include "commands.h"
- #include "session.h"
- #include "smtp.h"
- #include "usock.h"
- #include "mailbox.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: look.c,v 1.17 1997/09/07 00:31:16 root Exp root $";
- #endif
-
- static void look_input (int unused,void *p1,void *p2);
- extern int sockblock (int s,int value);
-
- struct look {
- struct session *sp; /* our look session */
- int user; /* socket we look at */
- };
-
-
- int
- dolook(int argc OPTIONAL, char *argv[],void *p OPTIONAL)
- {
- struct look lk;
- struct usock *up;
- int chat;
- char *cp;
- char const *cp2;
- char name[20];
- char buf[MBXLINE];
- int i, block;
-
- /* Check if this comes from console - WG7J*/
- if (Curproc->input != Command->input)
- return 0;
-
- #ifdef MAILBOX
- /* Find the user ! */
- lk.user = atoi (argv[1]); /* store socket #, or illegal # if callsign */
- for (i = 0; i < NUMMBX; i++) {
- if (Mbox[i] == NULLMBX)
- continue;
- if (!stricmp (Mbox[i]->name, argv[1]))
- break;
- if (lk.user && Mbox[i]->user == lk.user)
- break;
- }
- if (i != NUMMBX) {
- lk.user = Mbox[i]->user;
- strncpy (name, Mbox[i]->name, 20);
- } else {
- #endif
- lk.user = atoi (argv[1]);
- sprintf (name, "socket %d", lk.user);
- #ifdef MAILBOX
- }
- #endif
-
- if ((up = itop (lk.user)) == NULLUSOCK) {
- tputs ("User socket error!\n");
- return 0;
- }
- if (up->look) {
- tprintf ("Already looking at %s\n", argv[1]);
- return 0;
- }
- if (lk.user == Curproc->input || lk.user == Curproc->output) {
- tputs ("Can not look at myself!\n");
- return 0;
- }
- /* Now everything seems okay ! Get a session */
- if ((lk.sp = newsession (name, LOOK, 1)) == NULLSESSION) {
- tputs (TooManySessions);
- return 0;
- }
-
- up->look = Curproc; /* Tell the socket to echo data to this process ! */
- chat = 0;
- block = sockblock (Curproc->input, SOCK_NORXBLOCK);
-
- tprintf ("%s session %d looking at %s\n", Sestypes[lk.sp->type], lk.sp->index, argv[1]);
-
- /* Process whatever's typed on the terminal */
- memset (buf, 0, MBXLINE); /* Clear the input buffer */
- while (nb_recvline (Curproc->input, (unsigned char *) buf, sizeof(buf) - 1) >= 0) {
- if (itop (lk.user) == NULLUSOCK)
- break;
- if (buf[0] == '/') {
- cp = skipnonwhite (buf);
- cp = skipwhite (cp);
- /* process commands */
- switch (tolower (buf[1])) {
- case 'h':
- case '?':
- #ifdef MAILBOX
- tputs ("<Cmds>: /c-chat /i-insert /m-msg /q-quit\n");
- #else
- tputs ("<Cmds>: /q-quit\n");
- #endif
- break;
- #ifdef MAILBOX
- case 'm': /* Send a message to the user */
- if (i == NUMMBX) /* Not a mailbox user */
- break;
- #if 0
- cp = &buf[2];
- if (buf[2] == ' ')
- cp = &buf[3];
- #endif
- usprintf (lk.user, "<sysop>: %s", cp);
- break;
- case 'c': /* Initiate chat mode */
- if (chat || i == NUMMBX)
- /* Already in 'chat' mode or not a mailbox user */
- break;
- (void) usputs (lk.user, "*** SYSOP Initiated CHAT.\n");
- up->look = NULL; /* Disable echoing in socket layer */
- /* Now we need to redirect the network input
- * from the user's bbs process to the chat process
- */
- lk.sp->proc1 = newproc ("CHAT Server", 1024, look_input, 0,
- (void *)&lk, NULL, 0);
- chat = 1;
- break;
- #endif
- case 'i':
- #if 0
- cp = skipnonwhite (buf);
- cp = skipwhite (cp);
- #endif
- up->insertptr = up->insertbuf = strdup (cp);
- (void) usputs (lk.user, cp);
- break;
- case 'b':
- case 'e':
- case 'q': /* quit chat mode, or look mode */
- #ifdef MAILBOX
- if (!chat)
- goto done;
-
- lk.sp->proc1 = NULLPROC;
- up->look = Curproc; /* Enable echoing in socket layer */
- (void) usputs (lk.user, "*** BACK in mailbox\n");
- kpause (500);
- kwait (NULL); /* wait for the death of look_input */
- chat = 0;
- #else
- goto done;
- #endif
- break;
- default:
- break;
- }
- }
- #ifdef MAILBOX
- else if (chat)
- usprintf (lk.user, "<sysop>: %s", buf);
- #endif
-
- usflush (lk.user);
- usflush (Curproc->output);
- memset (buf, 0, MBXLINE); /* Clear the input buffer */
- }
- done:
- (void) sockblock (Curproc->input, block);
- /* A 'close' command was given, or user disconnected.
- * Notify the user, kill the receiver input task and wait for a response
- * from the user before freeing the session.
- */
- cp2 = sockerr (lk.sp->input);
- tprintf ("\n%s session %u closed: %s\n", Sestypes[lk.sp->type], lk.sp->index,
- (cp2 != NULLCHAR) ? cp2 : "EOF");
-
- if ((up = itop (lk.user)) != NULLUSOCK) /* Make sure socket is still there */
- up->look = NULL;
- #ifdef MAILBOX
- if (lk.sp->proc1 != NULLPROC) {
- /* kill the receive process */
- lk.sp->proc1 = NULLPROC;
- if (up) {
- (void) usputs (lk.user, "*** BACK in mailbox\n");
- usflush (lk.user);
- }
- }
- #endif
- (void) keywait (NULLCHAR, 1);
- freesession (lk.sp);
- return 0;
- }
-
-
- #ifdef MAILBOX
- /* Task that read the user's input socket (that formerly went to the socket
- * process), and sends it to the look session !
- */
- void
- look_input(unused,p1,p2)
- int unused OPTIONAL;
- void *p1;
- void *p2 OPTIONAL;
- {
- struct session *sp;
- struct usock *up;
- int user,c;
- int block;
- int done = 0;
-
- sp = ((struct look *)p1)->sp;
- user = ((struct look *)p1)->user;
-
- if ((up = itop (user)) == NULLUSOCK) {
- /* Make sure our parent doesn't try to kill us after we exit */
- sp->proc1 = NULLPROC;
- return;
- }
-
- /* Suspend the process that owns the socket */
- suspend (up->owner);
-
- /* Get current blocking mode and set to non-block */
- block = sockblock (user, SOCK_NORXBLOCK);
-
- /* Process input on the users socket connection */
- while (!done) {
- while ((c = recvchar (user)) == EOF) {
- if (errno != EWOULDBLOCK || sp->proc1 == NULLPROC) {
- done = 1;
- break;
- }
- kpause (500);
- }
- if (!done)
- tputc ((unsigned char)c);
- }
- if (sp->proc1 != NULLPROC)
- tputs ("*** Remote user disconnected!\n");
-
- /* Reset to original blocking mode */
- (void) sockblock (user, block);
-
- /* Make sure our parent doesn't try to kill us after we exit */
- sp->proc1 = NULLPROC;
-
- /* Alert the parent, in case the chat was terminated by losing the
- * user connection. This in effect will close the look session
- */
- alert (sp->proc, ENOTCONN);
-
- /* Resume the process that owns the socket */
- resume (up->owner);
- }
- #endif /* MAILBOX */
-
- #endif /* LOOKSESSION */
-